package com.afollestad.materialdialogs;

import com.afollestad.materialdialogs.utils.DialogUtils;
import com.afollestad.materialdialogs.utils.ResUtil;
import ohos.agp.components.*;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.global.configuration.Configuration;

public class DefaultRvAdapter extends BaseItemProvider {
    private int mLayoutRes;
    private MaterialDialog mDialog;
    private final GravityEnum mItemGravity;
    private InternalListCallback mCallback;
    private Context mContext;

    DefaultRvAdapter(MaterialDialog dialog, int layoutRes, Context context) {
        mDialog = dialog;
        mLayoutRes = layoutRes;
        mItemGravity = dialog.builder.itemsGravity;
        mContext = context;
    }

    void setCallback(InternalListCallback callback) {
        mCallback = callback;
    }

    @Override
    public int getCount() {
        return mDialog.builder.items.size();
    }

    @Override
    public Object getItem(int i) {
        return mDialog.builder.items.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public Component getComponent(int index, Component component, ComponentContainer componentContainer) {
        if (component == null) {
            component = LayoutScatter.getInstance(mContext).parse(mLayoutRes, componentContainer, false);
        }
        DialogUtils.setBackgroundCompat(component, mDialog.getListSelector());
        onPrepareView(index, component);
        return component;
    }

    private void onPrepareView(int index, Component component) {
        try {
            boolean disabled = DialogUtils.isIn(index, mDialog.builder.disabledIndices);
            int itemTextColor = disabled ? DialogUtils.adjustAlpha(ResourceTable.Color_core_material_gray, 0.4f) : ResUtil.getColor(mContext, ResourceTable.Color_core_material_gray);
            component.setEnabled(!disabled);
            boolean selected;
            switch (mDialog.listType) {
                case SINGLE:
                    RadioButton radioButton = (RadioButton) component.findComponentById(ResourceTable.Id_md_control);
                    selected = mDialog.builder.selectedIndex == index;
                    radioButton.setChecked(selected);
                    radioButton.setEnabled(!disabled);
                    if (radioButton.isChecked()) {
                        setAbsButtonBackgroundElement(radioButton, ResourceTable.Media_abc_btn_radio_to_on_mtrl_015, disabled);
                    } else {
                        setAbsButtonBackgroundElement(radioButton, ResourceTable.Media_abc_btn_radio_to_on_mtrl_000, disabled);
                    }

                    break;
                case MULTI:
                    Checkbox checkbox = (Checkbox) component.findComponentById(ResourceTable.Id_md_control);
                    selected = mDialog.selectedIndicesList.contains(index);
                    checkbox.setChecked(selected);
                    checkbox.setEnabled(!disabled);
                    if (checkbox.isChecked()) {
                        setAbsButtonBackgroundElement(checkbox, ResourceTable.Media_abc_btn_check_to_on_mtrl_015, disabled);
                    } else {
                        setAbsButtonBackgroundElement(checkbox, ResourceTable.Media_abc_btn_check_to_on_mtrl_000, disabled);
                    }

                    break;
            }
            Text title = (Text) component.findComponentById(ResourceTable.Id_md_title);
            String name = (String) getItem(index);
            title.setText(name);

            setupGravity((ComponentContainer) component);

            if (mDialog.builder.itemIds != null) {
                if (index < mDialog.builder.itemIds.length) {
                    component.setId(mDialog.builder.itemIds[index]);
                } else {
                    component.setId(-1);
                }
            }
            ComponentContainer group = (ComponentContainer) component;
            if (group.getChildCount() == 2) {
                // Remove circular selector from check boxes and radio buttons on Lollipop
                if (group.getComponentAt(0) instanceof Button) {
                    group.getComponentAt(0).setBackground(null);
                } else if (group.getComponentAt(1) instanceof Button) {
                    group.getComponentAt(1).setBackground(null);
                }
            }
            component.setClickedListener(view -> onItemClicked(view, index));
            if (mDialog.builder.listLongCallback != null) {
                component.setLongClickedListener(view -> onItemLongClicked(view, index));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * This method is used to set background element & background color of radiobutton & checkbox
     *
     * @param absButton Radiobutton/Checkbox
     * @param drawable  Resource drawable for checked/uncheked
     * @param disabled  disabled state to set the color
     */
    private void setAbsButtonBackgroundElement(AbsButton absButton, int drawable, boolean disabled) {
        absButton.setButtonElement(ResUtil.getPixelMapDrawable(mContext, drawable));
        if (disabled) {
            absButton.setAlpha(0.3f);
        }
    }

    private void setupGravity(ComponentContainer view) {
        final DirectionalLayout itemRoot = (DirectionalLayout) view;
        final int gravityInt = mItemGravity.getGravityInt();
        itemRoot.setAlignment(gravityInt | TextAlignment.VERTICAL_CENTER);
        if (view.getChildCount() == 2) {
            if (mItemGravity == GravityEnum.END
                    && !isRTL()
                    && view.getComponentAt(0) instanceof Button) {
                Button first = (Button) view.getComponentAt(0);
                view.removeComponent(first);

                Text second = (Text) view.getComponentAt(0);
                view.removeComponent(second);
                second.setPadding(
                        second.getPaddingRight(),
                        second.getPaddingTop(),
                        second.getPaddingLeft(),
                        second.getPaddingBottom());

                view.addComponent(second);
                view.addComponent(first);
            } else if (mItemGravity == GravityEnum.START
                    && isRTL()
                    && view.getComponentAt(1) instanceof Button) {
                Button first = (Button) view.getComponentAt(1);
                view.removeComponent(first);

                Text second = (Text) view.getComponentAt(0);
                view.removeComponent(second);
                second.setPadding(
                        second.getPaddingRight(),
                        second.getPaddingTop(),
                        second.getPaddingRight(),
                        second.getPaddingBottom());

                view.addComponent(first);
                view.addComponent(second);
            }
        }
    }

    private boolean isRTL() {
        Configuration config = mDialog.getBuilder().getContext().getResourceManager().getConfiguration();
        return config.isLayoutRTL;
    }

    private void onItemClicked(Component component, int index) {
        if (mCallback != null) {
            CharSequence text = null;
            if (mDialog.builder.items != null) {
                text = mDialog.builder.items.get(index);
            }
            mCallback.onItemSelected(mDialog, component, index, text, false);
        }
    }

    private void onItemLongClicked(Component component, int index) {
        if (mCallback != null) {
            CharSequence text = null;
            if (mDialog.builder.items != null) {
                text = mDialog.builder.items.get(index);
            }
            mCallback.onItemSelected(mDialog, component, index, text, true);
        }
    }

    interface InternalListCallback {
        boolean onItemSelected(MaterialDialog dialog, Component itemView, int position, CharSequence text, boolean longPress);
    }
}
